/*     */ package com.zimbra.cs.service.mail;
/*     */ 
/*     */ import com.google.common.base.Joiner;
/*     */ import com.zimbra.client.ZFolder;
/*     */ import com.zimbra.client.ZMailbox;
/*     */ import com.zimbra.client.ZMailbox.Options;
/*     */ import com.zimbra.client.ZMountpoint;
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.auth.ZAuthToken;
/*     */ import com.zimbra.common.mailbox.Color;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.MailConstants;
/*     */ import com.zimbra.common.soap.SoapProtocol;
/*     */ import com.zimbra.common.util.ArrayUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.mailbox.Flag.FlagInfo;
/*     */ import com.zimbra.cs.mailbox.Folder;
/*     */ import com.zimbra.cs.mailbox.MailItem.TargetConstraint;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailServiceException;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxManager;
/*     */ import com.zimbra.cs.mailbox.Mountpoint;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.mailbox.util.TagUtil;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.session.Session;
/*     */ import com.zimbra.cs.session.SoapSession;
/*     */ import com.zimbra.cs.session.SoapSession.DelegateSession;
/*     */ import com.zimbra.cs.util.AccountUtil;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import java.util.ArrayList;
/*     */ import java.util.HashMap;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Map.Entry;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class ItemAction
/*     */   extends MailDocumentHandler
/*     */ {
/*  62 */   protected static final String[] OPERATION_PATH = { "action", "op" };
/*  63 */   protected static final String[] TARGET_ITEM_PATH = { "action", "id" };
/*     */   public static final String OP_TAG = "tag";
/*     */   public static final String OP_FLAG = "flag";
/*     */   public static final String OP_PRIORITY = "priority";
/*     */   public static final String OP_READ = "read";
/*     */   public static final String OP_COLOR = "color";
/*     */   public static final String OP_HARD_DELETE = "delete";
/*     */   public static final String OP_RECOVER = "recover";
/*     */   public static final String OP_DUMPSTER_DELETE = "dumpsterdelete";
/*     */   public static final String OP_MOVE = "move";
/*     */   public static final String OP_COPY = "copy";
/*     */   public static final String OP_SPAM = "spam";
/*     */   public static final String OP_TRASH = "trash";
/*     */   public static final String OP_RENAME = "rename";
/*     */   public static final String OP_UPDATE = "update";
/*     */   public static final String OP_LOCK = "lock";
/*     */   public static final String OP_UNLOCK = "unlock";
/*     */   public static final String OP_INHERIT = "inherit";
/*     */   public static final String OP_MUTE = "mute";
/*     */   
/*     */   public Element handle(Element request, Map<String, Object> context)
/*     */     throws ServiceException
/*     */   {
/*  86 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*     */     
/*  88 */     Element action = request.getElement("action");
/*  89 */     String operation = action.getAttribute("op").toLowerCase();
/*     */     
/*  91 */     String successes = handleCommon(context, request, operation, MailItem.Type.UNKNOWN);
/*     */     
/*  93 */     Element response = zsc.createElement(MailConstants.ITEM_ACTION_RESPONSE);
/*  94 */     Element act = response.addUniqueElement("action");
/*  95 */     act.addAttribute("id", successes);
/*  96 */     act.addAttribute("op", operation);
/*  97 */     return response;
/*     */   }
/*     */   
/*     */   protected String getOperation(String opAttr)
/*     */   {
/* 102 */     return (opAttr.startsWith("!") ? opAttr.substring(1) : opAttr).toLowerCase();
/*     */   }
/*     */   
/*     */   protected String handleCommon(Map<String, Object> context, Element request, String opAttr, MailItem.Type type) throws ServiceException
/*     */   {
/* 107 */     Element action = request.getElement("action");
/* 108 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/* 109 */     Mailbox mbox = getRequestedMailbox(zsc);
/* 110 */     OperationContext octxt = getOperationContext(zsc, context);
/* 111 */     SoapProtocol responseProto = zsc.getResponseProtocol();
/*     */     
/*     */ 
/* 114 */     boolean flagValue = !opAttr.startsWith("!");
/* 115 */     String opStr = getOperation(opAttr);
/*     */     
/*     */ 
/* 118 */     List<Integer> local = new ArrayList();
/* 119 */     Map<String, StringBuilder> remote = new HashMap();
/* 120 */     partitionItems(zsc, action.getAttribute("id"), local, remote);
/* 121 */     if ((remote.isEmpty()) && (local.isEmpty())) {
/* 122 */       return "";
/*     */     }
/*     */     
/*     */ 
/* 126 */     Account remoteNotify = forceRemoteSession(zsc, context, octxt, opStr, action);
/*     */     
/*     */ 
/* 129 */     StringBuilder successes = proxyRemoteItems(action, remote, request, context);
/*     */     
/*     */ 
/* 132 */     if (!local.isEmpty()) {
/* 133 */       String constraint = action.getAttribute("tcon", null);
/* 134 */       MailItem.TargetConstraint tcon = MailItem.TargetConstraint.parseConstraint(mbox, constraint);
/*     */       
/*     */ 
/*     */       String localResults;
/*     */       
/* 139 */       if (opStr.equals("tag")) {
/* 140 */         String tagName = action.getAttribute("tn", null);
/* 141 */         if (tagName == null) {
/* 142 */           if (action.getAttribute("tag") == null) {
/* 143 */             throw ServiceException.INVALID_REQUEST("missing required attribute: tn", null);
/*     */           }
/* 145 */           tagName = TagUtil.tagIdToName(mbox, octxt, (int)action.getAttributeLong("tag"));
/*     */         }
/* 147 */         localResults = ItemActionHelper.TAG(octxt, mbox, responseProto, local, type, tagName, flagValue, tcon).getResult(); } else { String localResults;
/* 148 */         if (opStr.equals("flag")) {
/* 149 */           localResults = ItemActionHelper.FLAG(octxt, mbox, responseProto, local, type, flagValue, tcon).getResult(); } else { String localResults;
/* 150 */           if (opStr.equals("priority")) {
/* 151 */             localResults = ItemActionHelper.PRIORITY(octxt, mbox, responseProto, local, type, flagValue, tcon).getResult(); } else { String localResults;
/* 152 */             if (opStr.equals("read")) {
/* 153 */               localResults = ItemActionHelper.READ(octxt, mbox, responseProto, local, type, flagValue, tcon).getResult(); } else { String localResults;
/* 154 */               if (opStr.equals("color")) {
/* 155 */                 Color color = getColor(action);
/* 156 */                 localResults = ItemActionHelper.COLOR(octxt, mbox, responseProto, local, type, tcon, color).getResult(); } else { String localResults;
/* 157 */                 if (opStr.equals("delete")) {
/* 158 */                   localResults = ItemActionHelper.HARD_DELETE(octxt, mbox, responseProto, local, type, tcon).getResult(); } else { String localResults;
/* 159 */                   if (opStr.equals("recover")) {
/* 160 */                     ItemId iidFolder = new ItemId(action.getAttribute("l"), zsc);
/* 161 */                     localResults = ItemActionHelper.RECOVER(octxt, mbox, responseProto, local, type, tcon, iidFolder).getResult(); } else { String localResults;
/* 162 */                     if (opStr.equals("dumpsterdelete")) {
/* 163 */                       localResults = ItemActionHelper.DUMPSTER_DELETE(octxt, mbox, responseProto, local, type, tcon).getResult(); } else { String localResults;
/* 164 */                       if (opStr.equals("trash")) {
/* 165 */                         ItemId iidTrash = new ItemId(mbox, 3);
/* 166 */                         localResults = ItemActionHelper.MOVE(octxt, mbox, responseProto, local, type, tcon, iidTrash).getResult(); } else { String localResults;
/* 167 */                         if (opStr.equals("move")) {
/* 168 */                           ItemId iidFolder = new ItemId(action.getAttribute("l"), zsc);
/* 169 */                           localResults = ItemActionHelper.MOVE(octxt, mbox, responseProto, local, type, tcon, iidFolder).getResult(); } else { String localResults;
/* 170 */                           if (opStr.equals("copy")) {
/* 171 */                             ItemId iidFolder = new ItemId(action.getAttribute("l"), zsc);
/* 172 */                             localResults = ItemActionHelper.COPY(octxt, mbox, responseProto, local, type, tcon, iidFolder).getResult(); } else { String localResults;
/* 173 */                             if (opStr.equals("spam")) {
/* 174 */                               String defaultFolder = (flagValue ? 4 : 2) + "";
/* 175 */                               ItemId iidFolder = new ItemId(action.getAttribute("l", defaultFolder), zsc);
/* 176 */                               localResults = ItemActionHelper.SPAM(octxt, mbox, responseProto, local, type, flagValue, tcon, iidFolder).getResult(); } else { String localResults;
/* 177 */                               if (opStr.equals("rename")) {
/* 178 */                                 String name = action.getAttribute("name");
/* 179 */                                 ItemId iidFolder = new ItemId(action.getAttribute("l", "-1"), zsc);
/* 180 */                                 localResults = ItemActionHelper.RENAME(octxt, mbox, responseProto, local, type, tcon, name, iidFolder).getResult(); } else { String localResults;
/* 181 */                                 if (opStr.equals("update")) {
/* 182 */                                   String folderId = action.getAttribute("l", null);
/* 183 */                                   ItemId iidFolder = new ItemId(folderId == null ? "-1" : folderId, zsc);
/* 184 */                                   if (!iidFolder.belongsTo(mbox))
/* 185 */                                     throw ServiceException.INVALID_REQUEST("cannot move item between mailboxes", null);
/* 186 */                                   if ((folderId != null) && (iidFolder.getId() <= 0)) {
/* 187 */                                     throw MailServiceException.NO_SUCH_FOLDER(iidFolder.getId());
/*     */                                   }
/* 189 */                                   String name = action.getAttribute("name", null);
/* 190 */                                   String flags = action.getAttribute("f", null);
/* 191 */                                   String[] tags = TagUtil.parseTags(action, mbox, octxt);
/* 192 */                                   Color color = getColor(action);
/* 193 */                                   localResults = ItemActionHelper.UPDATE(octxt, mbox, responseProto, local, type, tcon, name, iidFolder, flags, tags, color).getResult(); } else { String localResults;
/* 194 */                                   if (opStr.equals("lock")) {
/* 195 */                                     localResults = ItemActionHelper.LOCK(octxt, mbox, responseProto, local, type, tcon).getResult(); } else { String localResults;
/* 196 */                                     if (opStr.equals("unlock")) {
/* 197 */                                       localResults = ItemActionHelper.UNLOCK(octxt, mbox, responseProto, local, type, tcon).getResult(); } else { String localResults;
/* 198 */                                       if (opStr.equals("inherit")) {
/* 199 */                                         mbox.alterTag(octxt, ArrayUtil.toIntArray(local), type, Flag.FlagInfo.NO_INHERIT, false, tcon);
/* 200 */                                         localResults = Joiner.on(",").join(local);
/* 201 */                                       } else if ((opStr.equals("mute")) && (type == MailItem.Type.CONVERSATION))
/*     */                                       {
/* 203 */                                         String localResults = ItemActionHelper.TAG(octxt, mbox, responseProto, local, type, Flag.FlagInfo.MUTED.toString(), flagValue, null).getResult();
/* 204 */                                         if (flagValue)
/*     */                                         {
/* 206 */                                           ItemActionHelper.READ(octxt, mbox, responseProto, local, type, flagValue, null).getResult();
/*     */                                         }
/*     */                                       } else {
/* 209 */                                         throw ServiceException.INVALID_REQUEST("unknown operation: " + opStr, null); } } } } } } } } } } } } } } } } }
/*     */       String localResults;
/* 211 */       successes.append(successes.length() > 0 ? "," : "").append(localResults);
/*     */     }
/*     */     
/*     */ 
/* 215 */     if (remoteNotify != null) {
/* 216 */       proxyRequest(zsc.createElement(MailConstants.NO_OP_REQUEST), context, remoteNotify.getId());
/*     */     }
/*     */     
/* 219 */     return successes.toString();
/*     */   }
/*     */   
/*     */   public static Color getColor(Element action) throws ServiceException {
/* 223 */     String rgb = action.getAttribute("rgb", null);
/* 224 */     byte c = (byte)(int)action.getAttributeLong("color", -1L);
/* 225 */     if ((rgb == null) && (c < 0))
/* 226 */       return new Color(-1L);
/* 227 */     if (rgb == null) {
/* 228 */       return new Color(c);
/*     */     }
/* 230 */     return new Color(rgb);
/*     */   }
/*     */   
/*     */ 
/*     */   private Account forceRemoteSession(ZimbraSoapContext zsc, Map<String, Object> context, OperationContext octxt, String op, Element action)
/*     */     throws ServiceException
/*     */   {
/* 237 */     if (!zsc.isNotificationEnabled()) {
/* 238 */       return null;
/*     */     }
/*     */     
/* 241 */     Session session = (Session)context.get("zimbra.session");
/* 242 */     if ((session instanceof SoapSession.DelegateSession)) {
/* 243 */       session = ((SoapSession.DelegateSession)session).getParentSession();
/*     */     }
/* 245 */     if ((!(session instanceof SoapSession)) || (session.getMailbox() == null)) {
/* 246 */       return null;
/*     */     }
/* 248 */     SoapSession ss = (SoapSession)session;
/*     */     
/*     */ 
/* 251 */     if ((!op.equals("move")) && (!op.equals("copy")) && (!op.equals("spam")) && (!op.equals("rename")) && (!op.equals("update"))) {
/* 252 */       return null;
/*     */     }
/* 254 */     String folderStr = action.getAttribute("l", null);
/* 255 */     if (folderStr == null) {
/* 256 */       return null;
/*     */     }
/*     */     
/*     */ 
/* 260 */     ItemId iidFolder = new ItemId(folderStr, zsc);ItemId iidRequested = iidFolder;
/* 261 */     Account owner = null;
/* 262 */     int hopCount = 0;
/* 263 */     ZAuthToken zat = null;
/* 264 */     while (hopCount < 5) {
/* 265 */       owner = Provisioning.getInstance().getAccountById(iidFolder.getAccountId());
/* 266 */       if (Provisioning.onLocalServer(owner)) {
/*     */         try {
/* 268 */           Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(owner);
/* 269 */           Folder folder = mbox.getFolderById(octxt, iidFolder.getId());
/* 270 */           if (!(folder instanceof Mountpoint))
/*     */             break;
/* 272 */           iidFolder = ((Mountpoint)folder).getTarget();
/*     */         }
/*     */         catch (ServiceException e) {
/*     */           break;
/*     */         }
/*     */       }
/* 278 */       if (zat == null) {
/* 279 */         AuthToken at = AuthToken.getCsrfUnsecuredAuthToken(zsc.getAuthToken());
/* 280 */         String pxyAuthToken = at.getProxyAuthToken();
/* 281 */         zat = pxyAuthToken == null ? at.toZAuthToken() : new ZAuthToken(pxyAuthToken);
/*     */       }
/* 283 */       ZMailbox.Options zoptions = new ZMailbox.Options(zat, AccountUtil.getSoapUri(owner));
/* 284 */       zoptions.setNoSession(true);
/* 285 */       zoptions.setTargetAccount(owner.getId());
/* 286 */       zoptions.setTargetAccountBy(Key.AccountBy.id);
/* 287 */       ZMailbox zmbx = ZMailbox.getMailbox(zoptions);
/* 288 */       ZFolder zfolder = zmbx.getFolderById(iidFolder.toString(zsc.getAuthtokenAccountId()));
/* 289 */       if (!(zfolder instanceof ZMountpoint))
/*     */         break;
/* 291 */       iidFolder = new ItemId(((ZMountpoint)zfolder).getCanonicalRemoteId(), zsc.getAuthtokenAccountId());
/*     */       
/* 293 */       hopCount++;
/*     */     }
/* 295 */     if (hopCount >= 5) {
/* 296 */       throw MailServiceException.TOO_MANY_HOPS(iidRequested);
/*     */     }
/*     */     
/*     */ 
/* 300 */     action.addAttribute("l", iidFolder.toString());
/*     */     
/*     */ 
/* 303 */     if (iidFolder.belongsTo(session.getAuthenticatedAccountId()))
/* 304 */       return null;
/* 305 */     if (iidFolder.isLocal()) {
/* 306 */       ss.getDelegateSession(iidFolder.getAccountId());
/* 307 */       return null;
/*     */     }
/*     */     try {
/* 310 */       proxyRequest(zsc.createElement(MailConstants.NO_OP_REQUEST), context, owner.getId());
/* 311 */       return owner;
/*     */     } catch (ServiceException e) {}
/* 313 */     return null;
/*     */   }
/*     */   
/*     */ 
/*     */   static void partitionItems(ZimbraSoapContext zsc, String ids, List<Integer> local, Map<String, StringBuilder> remote)
/*     */     throws ServiceException
/*     */   {
/* 320 */     Account acct = getRequestedAccount(zsc);
/* 321 */     for (String target : ids.split(",")) {
/* 322 */       ItemId iid = new ItemId(target, zsc);
/* 323 */       if (iid.belongsTo(acct)) {
/* 324 */         local.add(Integer.valueOf(iid.getId()));
/*     */       } else {
/* 326 */         StringBuilder sb = (StringBuilder)remote.get(iid.getAccountId());
/* 327 */         if (sb == null) {
/* 328 */           remote.put(iid.getAccountId(), new StringBuilder(iid.toString()));
/*     */         } else {
/* 330 */           sb.append(',').append(iid.toString());
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   protected StringBuilder proxyRemoteItems(Element action, Map<String, StringBuilder> remote, Element request, Map<String, Object> context) throws ServiceException
/*     */   {
/* 338 */     String folderStr = action.getAttribute("l", null);
/* 339 */     if (folderStr != null)
/*     */     {
/* 341 */       ItemId iidFolder = new ItemId(folderStr, getZimbraSoapContext(context));
/* 342 */       action.addAttribute("l", iidFolder.toString());
/*     */     }
/*     */     
/* 345 */     StringBuilder successes = new StringBuilder();
/* 346 */     for (Map.Entry<String, StringBuilder> entry : remote.entrySet())
/*     */     {
/* 348 */       String itemIds = ((StringBuilder)entry.getValue()).toString();
/* 349 */       action.addAttribute("id", itemIds);
/*     */       
/* 351 */       String accountId = (String)entry.getKey();
/* 352 */       Element response = proxyRequest(request, context, accountId);
/*     */       try
/*     */       {
/* 355 */         String completed = response.getElement("action").getAttribute("id");
/* 356 */         successes.append((completed.length() > 0) && (successes.length() > 0) ? "," : "").append(completed);
/*     */       } catch (ServiceException e) {
/* 358 */         ZimbraLog.misc.warn("could not extract ItemAction successes from proxied response", e);
/*     */       }
/*     */     }
/*     */     
/* 362 */     return successes;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   protected static long validateGrantExpiry(String grantExpiry, long maxLifetime)
/*     */     throws ServiceException
/*     */   {
/* 375 */     long now = System.currentTimeMillis();
/* 376 */     long ret = grantExpiry == null ? now + maxLifetime : maxLifetime == 0L ? 0L : Long.valueOf(grantExpiry).longValue();
/* 377 */     if ((grantExpiry != null) && (maxLifetime != 0L) && ((ret == 0L) || (ret > now + maxLifetime))) {
/* 378 */       throw ServiceException.PERM_DENIED("share expiration policy conflict");
/*     */     }
/* 380 */     return ret;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/mail/ItemAction.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */